Feature · canvas
Canvas
The templating language behind every Blutui page: loops, variables, filters and template inheritance in plain HTML.
Loop to list
once one pass, holds
A for-loop is typed into team.html and the rendered list beside it fills one entry per iteration. Code on the left, result on the right.
views/components/visuals/canvas/v1.html
Static · three placements
{% for member in team %}
<article>
<h3>{{ member.name }}</h3>
<p>{{ member.role }}</p>
</article>
{% endfor %}▏
Rendered · /team
{% for member in team %}
<article>
<h3>{{ member.name }}</h3>
<p>{{ member.role }}</p>
</article>
{% endfor %}▏
Rendered · /team
{% for member in team %}
<article>
<h3>{{ member.name }}</h3>
<p>{{ member.role }}</p>
</article>
{% endfor %}▏
Rendered · /team
Animated · once
{% for member in team %}
<article>
<h3>{{ member.name }}</h3>
<p>{{ member.role }}</p>
</article>
{% endfor %}▏
Rendered · /team
Block fills the shell
loop runs on screen
A layout extends the default template: its body block lights up and the hero it defines slides into the slot between the template header and footer. Inheritance rather than output.
views/components/visuals/canvas/v2.html
Static · three placements
{% extends 'templates/default' %}
{% block body %}
<section class="hero">
<h1>Book a visit</h1>
</section>
{% endblock %}
Book a visit
See times{% extends 'templates/default' %}
{% block body %}
<section class="hero">
<h1>Book a visit</h1>
</section>
{% endblock %}
Book a visit
See times{% extends 'templates/default' %}
{% block body %}
<section class="hero">
<h1>Book a visit</h1>
</section>
{% endblock %}
Book a visit
See timesAnimated · loop
{% extends 'templates/default' %}
{% block body %}
<section class="hero">
<h1>Book a visit</h1>
</section>
{% endblock %}
Book a visit
See timesTemplate to page
cutoutonce one pass, holds
Cutout on a navy ground: two windows, the editor with views/layouts/home.html in front and the browser with the site it renders behind, both cropped by the frame. The template types out line by line, the preview bar sweeps and the page paints in. The moment is keyboard, so there is no cursor. The preview is a real site screenshot from the CDN — the one visual in the lab with an external image.
views/components/visuals/canvas/c1.html
Static · three placements
{% extends 'templates/default.html' %}
{% set plans = cms.collection('plans')
| sort_by('order') | slice(0, 3) %}
{% block body %}
{{ include('components/hero.html') }}
{% for plan in plans %}
<article class="plan">
<h3>{{ plan.name }}</h3>
<p>{{ plan.beds }} bed · {{ plan.baths }} bath</p>
</article>
{% endfor %}
{% endblock %}
{% extends 'templates/default.html' %}
{% set plans = cms.collection('plans')
| sort_by('order') | slice(0, 3) %}
{% block body %}
{{ include('components/hero.html') }}
{% for plan in plans %}
<article class="plan">
<h3>{{ plan.name }}</h3>
<p>{{ plan.beds }} bed · {{ plan.baths }} bath</p>
</article>
{% endfor %}
{% endblock %}
{% extends 'templates/default.html' %}
{% set plans = cms.collection('plans')
| sort_by('order') | slice(0, 3) %}
{% block body %}
{{ include('components/hero.html') }}
{% for plan in plans %}
<article class="plan">
<h3>{{ plan.name }}</h3>
<p>{{ plan.beds }} bed · {{ plan.baths }} bath</p>
</article>
{% endfor %}
{% endblock %}
Animated · once
{% extends 'templates/default.html' %}
{% set plans = cms.collection('plans')
| sort_by('order') | slice(0, 3) %}
{% block body %}
{{ include('components/hero.html') }}
{% for plan in plans %}
<article class="plan">
<h3>{{ plan.name }}</h3>
<p>{{ plan.beds }} bed · {{ plan.baths }} bath</p>
</article>
{% endfor %}
{% endblock %}
Overrides none — the file's own defaults